package com.huaxin.dss2.data.dao;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import com.huaxin.dss2.data.exception.jdbc.DataSourceNotFoundException;
import com.huaxin.dss2.util.PropertiesUtil;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

/**
 * @author : luqing
 * @date : 2018/7/14 12:43
 */
@Component
@Slf4j
public class OrgDataSource {

    private JdbcTemplate jdbcTemplate;



    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    private static Map<String,JdbcTemplate> jdbcTemplateMap = new ConcurrentHashMap<>();

    public JdbcTemplate getJdbcTemplate(String orgCode) throws DataSourceNotFoundException {
        return jdbcTemplateMap.get(orgCode);
    }

    public static Map<String,JdbcTemplate> getJdbcTemplateMap(){
        return Maps.newHashMap(jdbcTemplateMap);
    }

    public static Map<String,Map<String,String>> dataTypeMap = new HashMap<>();

    private DataSource createDataSource(String dbName) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(PropertiesUtil.getString("jdbc.connection.url")+"/"+dbName);
        dataSource.setUsername(PropertiesUtil.getString("jdbc.connection.username"));
        dataSource.setPassword(PropertiesUtil.getString("jdbc.connection.password"));


        dataSource.setMaxActive(300);
        dataSource.setInitialSize(1);
        dataSource.setMaxWait(60000);
        dataSource.setMinIdle(1);

        dataSource.setTimeBetweenEvictionRunsMillis(3000);
        dataSource.setMinEvictableIdleTimeMillis(300000);

        dataSource.setValidationQuery("SELECT 'x'");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);

        // 设置连接回收机制，解决连接溢出问题
        dataSource.setRemoveAbandoned(true);
        dataSource.setRemoveAbandonedTimeout(600);
        dataSource.setLogAbandoned(false);

        return dataSource;
    }


    public void refreshOrgDataSource(){

        List<String> dataBaseList = jdbcTemplate.queryForList("show databases", String.class);
        Map<String,JdbcTemplate> newJdbcTemplateMap = new HashMap<>();
        Map<String,JdbcTemplate> copyOfJdbcTemplateMap = new HashMap<>(jdbcTemplateMap);

        for(String dbName : dataBaseList){
            if(!dbName.startsWith("datadb_")) {
                continue;
            }
            String dataOrgCode = dbName.substring(7);
            JdbcTemplate jdbcTemplate = copyOfJdbcTemplateMap.remove(dataOrgCode.toLowerCase());
            if(null==jdbcTemplate){
                log.info("初始化历史数据库源datadb_{}",dataOrgCode);
                jdbcTemplate=new JdbcTemplate(createDataSource(dbName.toLowerCase()));
                newJdbcTemplateMap.put(dataOrgCode,jdbcTemplate);
            }
        }

        // 关闭无效数据源
        for(JdbcTemplate jt : copyOfJdbcTemplateMap.values()){
            ((DruidDataSource)jt.getDataSource()).close();
        }

        jdbcTemplateMap= Collections.unmodifiableMap(newJdbcTemplateMap);
        log.info("初始化历史数据库源完成");
    }

    public boolean hasDataSource(String orgCode){
        return jdbcTemplateMap.containsKey(orgCode);
    }

}
